
clear all

******************************************************************************
* Specify working directory
******************************************************************************

* For example
* cd "/Users/.../XYZ/"

global rawdata "Data/Raw_Data"
global tempdata "Data/Temp_Data"
global masterdata "Data/Master_Data"
global revisiondata "Data/RevisionRFS"
global revisionfigures = "Results/RevisionRFS/Figures"
global revisionoutput = "Results/RevisionRFS/Output"


#delimit ;

use "${revisiondata}/estimation/estimation_coeff_se_fund_ig_cf.dta", clear;
append using "${revisiondata}/estimation/estimation_coeff_se_bin_ig_cf.dta";
append using "${revisiondata}/estimation/estimation_coeff_se_bin_hy_cf.dta";

save "${revisiondata}/estimation/estimation_coefficients.dta", replace;


use "${revisiondata}/estimation/estimation_coeff_se_fund_ig_cf_yield.dta", clear;
append using "${revisiondata}/estimation/estimation_coeff_se_bin_ig_cf_yield.dta";
append using "${revisiondata}/estimation/estimation_coeff_se_bin_hy_cf_yield.dta";

save "${revisiondata}/estimation/estimation_coefficients_yield.dta", replace;


u date fundid bondid type_new2 assetclass bin bin_assetclass holding_bv price_zcb2 outaum_tot
	yield ytm rating_num LNtimetomat spread LNbv coupon price_eom price_coupon
	LNrweight_conditional Nholding ln_mp coupon_dec offering_amt
	observed_life_span observed_holding_mean timetomat outaum_assetclass 
	if LNrweight_conditional<.
	using "${revisiondata}/sample/Data1_us_europe_revision_rfs_v2_price.dta", clear;


gsort date bondid fundid;

gen holding_bv2 = holding_bv;
replace holding_bv2 = . if fundid == 0;

replace holding_bv2 = min(holding_bv2,offering_amt) if fundid>0;
egen Tholding_bv2 = sum(holding_bv2), by(date bondid);

replace holding_bv2 = max(offering_amt-Tholding_bv2,0) if fundid==0;
drop Tholding_bv2;
egen Tholding_bv2 = sum(holding_bv2), by(date bondid);

gen diff = Tholding_bv2 - offering_amt;
su diff, d;
drop if diff != 0;

gen holding = price_eom/100*holding_bv2;

/* Merge coefficients */
merge m:1 date fundid bin_assetclass using "${revisiondata}/estimation/estimation_coefficients.dta",
	keepusing(_b_ss_price_*)
	nogen keep(master match);

merge m:1 date fundid bin_assetclass using "${revisiondata}/estimation/estimation_coefficients_yield.dta",
	keepusing(_b_ss_yield_*)
	nogen keep(master match);
	
merge m:1 type_new2 fundid date using "${revisionoutput}/across_assetclass_coeff_se_cf.dta",
	keepusing(*)
	nogen keep(master match);
	
drop LNweight_assetclass LNoutweight_conditional1 LNoutweight_conditional2;
	
gen lambda = _b_LNoutweight_conditional1 if assetclass == 1;
replace lambda = _b_LNoutweight_conditional2 if assetclass == 2;

gegen aum_assetclass_inside = sum(holding), by(date fundid assetclass);

gen aum_assetclass = aum_assetclass_inside + outaum_assetclass;

gen aum_assetclass_sum = aum_assetclass;
bysort date fundid assetclass: replace aum_assetclass_sum = 0 if _n != 1;
gegen aum_tot = sum(aum_assetclass_sum), by(date fundid);

gen aum_ig = aum_assetclass;
bysort date fundid assetclass: replace aum_ig = 0 if _n != 1;
replace aum_ig = 0 if assetclass == 2;
gegen aum_assetclass1 = sum(aum_ig), by(date fundid);
	
gen aum_hy = aum_assetclass;
bysort date fundid assetclass: replace aum_hy = 0 if _n != 1;
replace aum_hy = 0 if assetclass == 1;
gegen aum_assetclass2 = sum(aum_hy), by(date fundid);

gen LNweight_assetclass = ln(aum_assetclass1/aum_assetclass2);


gen LNoutweight_conditional = ln(outaum_assetclass/aum_assetclass);
replace LNoutweight_conditional = -LNoutweight_conditional if assetclass == 1;
	
gen LNoutweight_conditional_ig = LNoutweight_conditional;
bysort date fundid assetclass: replace LNoutweight_conditional_ig = 0 if _n != 1;
replace LNoutweight_conditional_ig = 0 if assetclass == 2;
gegen LNoutweight_conditional1 = sum(LNoutweight_conditional_ig), by(date fundid);

gen LNoutweight_conditional_hy = LNoutweight_conditional;
bysort date fundid assetclass: replace LNoutweight_conditional_hy = 0 if _n != 1;
replace LNoutweight_conditional_hy = 0 if assetclass == 1;
gegen LNoutweight_conditional2 = sum(LNoutweight_conditional_hy), by(date fundid);

gen weight_assetclass = aum_assetclass/aum_tot;
gegen exclusive = max(weight_assetclass), by(date fundid);
replace exclusive = 0 if exclusive < 1;

replace lambda = 0 if exclusive == 1;

drop LNrweight_conditional;
gen LNrweight_conditional = ln(holding/outaum_assetclass);

save "${revisiondata}/counterfactuals/counterfactuals_data.dta", replace;


#delimit cr



/* -----------------------------------------------------------------------------

Counterfactual 2: Investment Grade Bonds Collectively Downgraded 

-----------------------------------------------------------------------------*/

clear all
set more off

set varabbrev off

/* choose user working directory */

******************************************************************************
* Specify working directory
******************************************************************************

* For example
* cd "/Users/.../XYZ/"

global rawdata "Data/Raw_Data"
global tempdata "Data/RevisionRFS/temp_data"
global masterdata "Data/Master_Data"
global revisiondata "Data/RevisionRFS"
global revisionfigures = "Results/RevisionRFS/Figures"
global revisionoutput = "Results/RevisionRFS/Output"

clear all
set more off
set type double

#delimit ;

forval q = `=tq(2006q1)'(1)`=tq(2020q3)' {;

di %tq `q';

#delimit ;
/* Load Data */
u "${revisiondata}/counterfactuals/counterfactuals_data.dta", clear;
keep if date==`q' & LNrweight_conditional<.;


/* Generate counterfactual variable */
gen rating_numLoop = rating_num; 
replace rating_numLoop = rating_numLoop + 1 if rating_numLoop <= 9;


/* Impose downward sloping demand as in KY (2019) */
replace _b_ss_price_iv = 0.99 if _b_ss_price_iv >= 1; 

/* Initial guess for price */
gen ln_priceLoop = ln_mp;

/* Set characteristics */
gen LNtimetomatLoop = LNtimetomat;  
gen spreadLoop = spread;
gen LNbvLoop = LNbv; 
gen coupon_decLoop = coupon_dec; 
 

/* Set AUM */
gen aumLoop = aum_tot;

/* Calculate within credit rating group latent demand (epsilon) plus the constant */
gen const_eps = LNrweight_conditional - (_b_ss_price_iv*ln_mp + _b_ss_price_tmt*LNtimetomat + _b_ss_price_spread*spread + _b_ss_price_bv*LNbv + _b_ss_price_rating*rating_num + _b_ss_price_coupon*coupon_dec);

/* Calculate across credit rating group latent demand (xi) plus fixed effect (alpha) */
gen alpha_xi = LNweight_assetclass - (LNoutweight_conditional1*_b_LNoutweight_conditional1 +LNoutweight_conditional2*_b_LNoutweight_conditional2);

/* Alpha_xi is only defined for one credit rating group --> set to zero otherwise */
replace alpha_xi = 0 if assetclass == 2;
replace alpha_xi = 0 if exclusive == 1;


/* Set coefficients */
foreach var of varlist _b_ss_price_iv _b_ss_price_tmt _b_ss_price_spread _b_ss_price_bv _b_ss_price_rating _b_ss_price_coupon{;
	gen `var'Loop = `var';
	};

/* Set the latent variable for within credit rating group */
gen latent = _b_ss_price_tmtLoop*LNtimetomatLoop + _b_ss_price_spreadLoop*spreadLoop + _b_ss_price_bvLoop*LNbvLoop + _b_ss_price_ratingLoop*rating_numLoop + 
 _b_ss_price_couponLoop*coupon_decLoop + const_eps;


#delimit ;

/* Solve for price */
forval j = 1/500 {;
	
	#delimit ;
	
	/* Update within credit rating group weights */

	gen double delta = exp(_b_ss_price_ivLoop*ln_priceLoop+latent);
	gegen double sum_delta = sum(delta), by(date fundid assetclass);

	gen double weight_conditional = delta/(1+sum_delta);
	
	#delimit ;
	/* Update across credit rating group weights */
	
	gen double inclusive_value = 1+sum_delta;
	
	gen double numerator = ( (inclusive_value)^lambda )*exp(alpha_xi);
	
	gen double numerator_once = numerator;
	bysort date fundid assetclass: replace numerator_once = 0 if _n != 1;
	
	gegen double denominator = sum(numerator_once), by(date fundid);

    gen double weight_across = numerator/denominator;
	
	
	#delimit ;
	/* Update bond specific weights */

	gen double weight = weight_conditional*weight_across;
	
	gegen double demand = sum(aumLoop*weight), by(date bondid);
	
	gegen double Ddemand = sum(aumLoop*( lambda*_b_ss_price_ivLoop*weight_conditional*weight_across*(1-weight_across)*weight_conditional + _b_ss_price_ivLoop*weight_conditional*(1-weight_conditional)*weight_across )/demand), by(date bondid);
	replace Ddemand = 1/(1-min(0,Ddemand));

	drop delta sum_delta weight_conditional inclusive_value numerator numerator_once denominator weight_across weight;

	/* Check convergence - Market Clearing */

	gen gap = ln(demand)-ln_priceLoop-LNbvLoop;

	sum gap;
	local gap = max(abs(r(min)),abs(r(max)));

	/* Update price */

	replace ln_priceLoop = ln_priceLoop+Ddemand*gap;

	drop demand Ddemand gap;

	/* Exit if converged */

	if `j'==1000 | `gap'<10^-4 {;
		di `j' _skip(5) `gap';

		egen ln_mpCF = min(ln_priceLoop), by(bondid);
		gen gap = `gap';

		continue, break;
	};
};

#delimit ;
/* Construct variables */
sort date bondid fundid;
qui by date bondid: keep if _n==1;

/* Construct yield changes */
gen price_CF = exp(ln_mpCF)*100;
gen yield_CF = -ln_mpCF/timetomat;
gen CF_pc_yield = 100*(yield_CF - yield)/yield;
gen CF_chg_yield = 100*(yield_CF - yield);


save "${revisiondata}/counterfactuals/cf_two_`q'.dta", replace;


};




#delimit cr

/* -----------------------------------------------------------------------------

Counterfactual 3: High Yield Bonds Collectively Downgraded 

-----------------------------------------------------------------------------*/

clear all
set more off

set varabbrev off

******************************************************************************
* Specify working directory
******************************************************************************

* For example
* cd "/Users/.../XYZ/"

global rawdata "Data/Raw_Data"
global tempdata "Data/RevisionRFS/temp_data"
global masterdata "Data/Master_Data"
global revisiondata "Data/RevisionRFS"
global revisionfigures = "Results/RevisionRFS/Figures"
global revisionoutput = "Results/RevisionRFS/Output"

clear all
set more off
set type double


#delimit ;

forval q = `=tq(2006q1)'(1)`=tq(2020q3)' {;

di %tq `q';

#delimit ;
/* Load Data */
u "${revisiondata}/counterfactuals/counterfactuals_data.dta", clear;
keep if date==`q' & LNrweight_conditional<.;


/* Generate counterfactual variable */
gen rating_numLoop = rating_num; 
replace rating_numLoop = rating_numLoop + 1 if rating_numLoop >= 11 & rating_numLoop < 20;


/* Impose downward sloping demand as in KY (2019) */
replace _b_ss_price_iv = 0.99 if _b_ss_price_iv >= 1; 

/* Initial guess for price */
gen ln_priceLoop = ln_mp;

/* Set characteristics */
gen LNtimetomatLoop = LNtimetomat;  
gen spreadLoop = spread;
gen LNbvLoop = LNbv; 
gen coupon_decLoop = coupon_dec; 
 

/* Set AUM */
gen aumLoop = aum_tot;

/* Calculate within credit rating group latent demand (epsilon) plus the constant */
gen const_eps = LNrweight_conditional - (_b_ss_price_iv*ln_mp + _b_ss_price_tmt*LNtimetomat + _b_ss_price_spread*spread + _b_ss_price_bv*LNbv + _b_ss_price_rating*rating_num + _b_ss_price_coupon*coupon_dec);

/* Calculate across credit rating group latent demand (xi) plus fixed effect (alpha) */
gen alpha_xi = LNweight_assetclass - (LNoutweight_conditional1*_b_LNoutweight_conditional1 +LNoutweight_conditional2*_b_LNoutweight_conditional2);

/* Alpha_xi is only defined for one credit rating group --> set to zero otherwise */
replace alpha_xi = 0 if assetclass == 2;
replace alpha_xi = 0 if exclusive == 1;


/* Set coefficients */
foreach var of varlist _b_ss_price_iv _b_ss_price_tmt _b_ss_price_spread _b_ss_price_bv _b_ss_price_rating _b_ss_price_coupon{;
	gen `var'Loop = `var';
	};

/* Set the latent variable for within credit rating group */
gen latent = _b_ss_price_tmtLoop*LNtimetomatLoop + _b_ss_price_spreadLoop*spreadLoop + _b_ss_price_bvLoop*LNbvLoop + _b_ss_price_ratingLoop*rating_numLoop + 
 _b_ss_price_couponLoop*coupon_decLoop + const_eps;


#delimit ;

/* Solve for price */
forval j = 1/500 {;
	
	#delimit ;
	
	/* Update within credit rating group weights */

	gen double delta = exp(_b_ss_price_ivLoop*ln_priceLoop+latent);
	gegen double sum_delta = sum(delta), by(date fundid assetclass);

	gen double weight_conditional = delta/(1+sum_delta);
	
	#delimit ;
	/* Update across credit rating group weights */
	
	gen double inclusive_value = 1+sum_delta;
	
	gen double numerator = ( (inclusive_value)^lambda )*exp(alpha_xi);
	
	gen double numerator_once = numerator;
	bysort date fundid assetclass: replace numerator_once = 0 if _n != 1;
	
	gegen double denominator = sum(numerator_once), by(date fundid);

    gen double weight_across = numerator/denominator;
	
	
	#delimit ;
	/* Update bond specific weights */

	gen double weight = weight_conditional*weight_across;
	
	gegen double demand = sum(aumLoop*weight), by(date bondid);
	
	gegen double Ddemand = sum(aumLoop*( lambda*_b_ss_price_ivLoop*weight_conditional*weight_across*(1-weight_across)*weight_conditional + _b_ss_price_ivLoop*weight_conditional*(1-weight_conditional)*weight_across )/demand), by(date bondid);
	replace Ddemand = 1/(1-min(0,Ddemand));

	drop delta sum_delta weight_conditional inclusive_value numerator numerator_once denominator weight_across weight;

	/* Check convergence - Market Clearing */

	gen gap = ln(demand)-ln_priceLoop-LNbvLoop;

	sum gap;
	local gap = max(abs(r(min)),abs(r(max)));

	/* Update price */

	replace ln_priceLoop = ln_priceLoop+Ddemand*gap;

	drop demand Ddemand gap;

	/* Exit if converged */

	if `j'==1000 | `gap'<10^-4 {;
		di `j' _skip(5) `gap';

		egen ln_mpCF = min(ln_priceLoop), by(bondid);
		gen gap = `gap';

		continue, break;
	};
};

#delimit ;
/* Construct variables */
sort date bondid fundid;
qui by date bondid: keep if _n==1;

/* Construct yield changes */
gen price_CF = exp(ln_mpCF)*100;
gen yield_CF = -ln_mpCF/timetomat;
gen CF_pc_yield = 100*(yield_CF - yield)/yield;
gen CF_chg_yield = 100*(yield_CF - yield);


save "${revisiondata}/counterfactuals/cf_three_`q'.dta", replace;


};


#delimit cr

/* -----------------------------------------------------------------------------

Counterfactual 4: Investment Grade Bonds Collectively Downgraded - Less Segmented

-----------------------------------------------------------------------------*/

clear all
set more off

set varabbrev off

******************************************************************************
* Specify working directory
******************************************************************************

* For example
* cd "/Users/.../XYZ/"

global rawdata "Data/Raw_Data"
global tempdata "Data/RevisionRFS/temp_data"
global masterdata "Data/Master_Data"
global revisiondata "Data/RevisionRFS"
global revisionfigures = "Results/RevisionRFS/Figures"
global revisionoutput = "Results/RevisionRFS/Output"

clear all
set more off
set type double

#delimit ;

forval q = `=tq(2006q1)'(1)`=tq(2020q3)' {;

di %tq `q';

#delimit ;
/* Load Data */
u "${revisiondata}/counterfactuals/counterfactuals_data.dta", clear;
keep if date==`q' & LNrweight_conditional<.;


/* Generate counterfactual variable */
gen rating_numLoop = rating_num; 
replace rating_numLoop = rating_numLoop + 1 if rating_numLoop <= 9;


/* Impose downward sloping demand as in KY (2019) */
replace _b_ss_price_iv = 0.99 if _b_ss_price_iv >= 1; 

/* Initial guess for price */
gen ln_priceLoop = ln_mp;

/* Set characteristics */
gen LNtimetomatLoop = LNtimetomat;  
gen spreadLoop = spread;
gen LNbvLoop = LNbv; 
gen coupon_decLoop = coupon_dec; 
 

/* Set AUM */
gen aumLoop = aum_tot;


/* Set lambda's equal to 0.95 for IG assetclass */
replace lambda = 0.95 if lambda != 0 & assetclass == 1;
replace _b_LNoutweight_conditional1 = 0.95;


/* Calculate within credit rating group latent demand (epsilon) plus the constant */
gen const_eps = LNrweight_conditional - (_b_ss_price_iv*ln_mp + _b_ss_price_tmt*LNtimetomat + _b_ss_price_spread*spread + _b_ss_price_bv*LNbv + _b_ss_price_rating*rating_num + _b_ss_price_coupon*coupon_dec);

/* Calculate across credit rating group latent demand (xi) plus fixed effect (alpha) */
gen alpha_xi = LNweight_assetclass - (LNoutweight_conditional1*_b_LNoutweight_conditional1 +LNoutweight_conditional2*_b_LNoutweight_conditional2);

/* Alpha_xi is only defined for one credit rating group --> set to zero otherwise */
replace alpha_xi = 0 if assetclass == 2;
replace alpha_xi = 0 if exclusive == 1;


/* Set coefficients */
foreach var of varlist _b_ss_price_iv _b_ss_price_tmt _b_ss_price_spread _b_ss_price_bv _b_ss_price_rating _b_ss_price_coupon{;
	gen `var'Loop = `var';
	};

/* Set the latent variable for within credit rating group */
gen latent = _b_ss_price_tmtLoop*LNtimetomatLoop + _b_ss_price_spreadLoop*spreadLoop + _b_ss_price_bvLoop*LNbvLoop + _b_ss_price_ratingLoop*rating_numLoop + 
 _b_ss_price_couponLoop*coupon_decLoop + const_eps;


#delimit ;

/* Solve for price */
forval j = 1/500 {;
	
	#delimit ;
	
	/* Update within credit rating group weights */

	gen double delta = exp(_b_ss_price_ivLoop*ln_priceLoop+latent);
	gegen double sum_delta = sum(delta), by(date fundid assetclass);

	gen double weight_conditional = delta/(1+sum_delta);
	
	#delimit ;
	/* Update across credit rating group weights */
	
	gen double inclusive_value = 1+sum_delta;
	
	gen double numerator = ( (inclusive_value)^lambda )*exp(alpha_xi);
	
	gen double numerator_once = numerator;
	bysort date fundid assetclass: replace numerator_once = 0 if _n != 1;
	
	gegen double denominator = sum(numerator_once), by(date fundid);

    gen double weight_across = numerator/denominator;
	
	
	#delimit ;
	/* Update bond specific weights */

	gen double weight = weight_conditional*weight_across;
	
	gegen double demand = sum(aumLoop*weight), by(date bondid);
	
	gegen double Ddemand = sum(aumLoop*( lambda*_b_ss_price_ivLoop*weight_conditional*weight_across*(1-weight_across)*weight_conditional + _b_ss_price_ivLoop*weight_conditional*(1-weight_conditional)*weight_across )/demand), by(date bondid);
	replace Ddemand = 1/(1-min(0,Ddemand));

	drop delta sum_delta weight_conditional inclusive_value numerator numerator_once denominator weight_across weight;

	/* Check convergence - Market Clearing */

	gen gap = ln(demand)-ln_priceLoop-LNbvLoop;

	sum gap;
	local gap = max(abs(r(min)),abs(r(max)));

	/* Update price */

	replace ln_priceLoop = ln_priceLoop+Ddemand*gap;

	drop demand Ddemand gap;

	/* Exit if converged */

	if `j'==1000 | `gap'<10^-4 {;
		di `j' _skip(5) `gap';

		egen ln_mpCF = min(ln_priceLoop), by(bondid);
		gen gap = `gap';

		continue, break;
	};
};

#delimit ;
/* Construct variables */
sort date bondid fundid;
qui by date bondid: keep if _n==1;

/* Construct yield changes */
gen price_CF = exp(ln_mpCF)*100;
gen yield_CF = -ln_mpCF/timetomat;
gen CF_pc_yield = 100*(yield_CF - yield)/yield;
gen CF_chg_yield = 100*(yield_CF - yield);


save "${revisiondata}/counterfactuals/cf_four_`q'.dta", replace;


};



#delimit cr


/* -----------------------------------------------------------------------------

Counterfactual 5: High Yield Bonds Collectively Downgraded - Less Segmented

-----------------------------------------------------------------------------*/

clear all
set more off

set varabbrev off

******************************************************************************
* Specify working directory
******************************************************************************

* For example
* cd "/Users/.../XYZ/"
}

global rawdata "Data/Raw_Data"
global tempdata "Data/RevisionRFS/temp_data"
global masterdata "Data/Master_Data"
global revisiondata "Data/RevisionRFS"
global revisionfigures = "Results/RevisionRFS/Figures"
global revisionoutput = "Results/RevisionRFS/Output"

clear all
set more off
set type double


#delimit ;

forval q = `=tq(2006q1)'(1)`=tq(2020q3)' {;

di %tq `q';

#delimit ;
/* Load Data */
u "${revisiondata}/counterfactuals/counterfactuals_data.dta", clear;
keep if date==`q' & LNrweight_conditional<.;


/* Generate counterfactual variable */
gen rating_numLoop = rating_num; 
replace rating_numLoop = rating_numLoop + 1 if rating_numLoop >= 11 & rating_numLoop < 20;


/* Impose downward sloping demand as in KY (2019) */
replace _b_ss_price_iv = 0.99 if _b_ss_price_iv >= 1; 

/* Initial guess for price */
gen ln_priceLoop = ln_mp;

/* Set characteristics */
gen LNtimetomatLoop = LNtimetomat;  
gen spreadLoop = spread;
gen LNbvLoop = LNbv; 
gen coupon_decLoop = coupon_dec; 
 

/* Set AUM */
gen aumLoop = aum_tot;


/* Set lambda's equal to 0.95 for HY assetclass */
replace lambda = 0.95 if lambda != 0 & assetclass == 2;
replace _b_LNoutweight_conditional2 = 0.95;

/* Calculate within credit rating group latent demand (epsilon) plus the constant */
gen const_eps = LNrweight_conditional - (_b_ss_price_iv*ln_mp + _b_ss_price_tmt*LNtimetomat + _b_ss_price_spread*spread + _b_ss_price_bv*LNbv + _b_ss_price_rating*rating_num + _b_ss_price_coupon*coupon_dec);

/* Calculate across credit rating group latent demand (xi) plus fixed effect (alpha) */
gen alpha_xi = LNweight_assetclass - (LNoutweight_conditional1*_b_LNoutweight_conditional1 +LNoutweight_conditional2*_b_LNoutweight_conditional2);

/* Alpha_xi is only defined for one credit rating group --> set to zero otherwise */
replace alpha_xi = 0 if assetclass == 2;
replace alpha_xi = 0 if exclusive == 1;


/* Set coefficients */
foreach var of varlist _b_ss_price_iv _b_ss_price_tmt _b_ss_price_spread _b_ss_price_bv _b_ss_price_rating _b_ss_price_coupon{;
	gen `var'Loop = `var';
	};

/* Set the latent variable for within credit rating group */
gen latent = _b_ss_price_tmtLoop*LNtimetomatLoop + _b_ss_price_spreadLoop*spreadLoop + _b_ss_price_bvLoop*LNbvLoop + _b_ss_price_ratingLoop*rating_numLoop + 
 _b_ss_price_couponLoop*coupon_decLoop + const_eps;


#delimit ;

/* Solve for price */
forval j = 1/500 {;
	
	#delimit ;
	
	/* Update within credit rating group weights */

	gen double delta = exp(_b_ss_price_ivLoop*ln_priceLoop+latent);
	gegen double sum_delta = sum(delta), by(date fundid assetclass);

	gen double weight_conditional = delta/(1+sum_delta);
	
	#delimit ;
	/* Update across credit rating group weights */
	
	gen double inclusive_value = 1+sum_delta;
	
	gen double numerator = ( (inclusive_value)^lambda )*exp(alpha_xi);
	
	gen double numerator_once = numerator;
	bysort date fundid assetclass: replace numerator_once = 0 if _n != 1;
	
	gegen double denominator = sum(numerator_once), by(date fundid);

    gen double weight_across = numerator/denominator;
	
	
	#delimit ;
	/* Update bond specific weights */

	gen double weight = weight_conditional*weight_across;
	
	gegen double demand = sum(aumLoop*weight), by(date bondid);
	
	gegen double Ddemand = sum(aumLoop*( lambda*_b_ss_price_ivLoop*weight_conditional*weight_across*(1-weight_across)*weight_conditional + _b_ss_price_ivLoop*weight_conditional*(1-weight_conditional)*weight_across )/demand), by(date bondid);
	replace Ddemand = 1/(1-min(0,Ddemand));

	drop delta sum_delta weight_conditional inclusive_value numerator numerator_once denominator weight_across weight;

	/* Check convergence - Market Clearing */

	gen gap = ln(demand)-ln_priceLoop-LNbvLoop;

	sum gap;
	local gap = max(abs(r(min)),abs(r(max)));

	/* Update price */

	replace ln_priceLoop = ln_priceLoop+Ddemand*gap;

	drop demand Ddemand gap;

	/* Exit if converged */

	if `j'==1000 | `gap'<10^-4 {;
		di `j' _skip(5) `gap';

		egen ln_mpCF = min(ln_priceLoop), by(bondid);
		gen gap = `gap';

		continue, break;
	};
};

#delimit ;
/* Construct variables */
sort date bondid fundid;
qui by date bondid: keep if _n==1;

/* Construct yield changes */
gen price_CF = exp(ln_mpCF)*100;
gen yield_CF = -ln_mpCF/timetomat;
gen CF_pc_yield = 100*(yield_CF - yield)/yield;
gen CF_chg_yield = 100*(yield_CF - yield);


save "${revisiondata}/counterfactuals/cf_five_`q'.dta", replace;


};



#delimit cr

/* -----------------------------------------------------------------------------

Counterfactual 6: ETF sector same size as in 2006Q1 --> AUM goes to MF

-----------------------------------------------------------------------------*/

clear all
set more off

set varabbrev off

******************************************************************************
* Specify working directory
******************************************************************************

* For example
* cd "/Users/.../XYZ/"

global rawdata "Data/Raw_Data"
global tempdata "Data/RevisionRFS/temp_data"
global masterdata "Data/Master_Data"
global revisiondata "Data/RevisionRFS"
global revisionfigures = "Results/RevisionRFS/Figures"
global revisionoutput = "Results/RevisionRFS/Output"

clear all
set more off
set type double

#delimit ;

forval q = `=tq(2006q1)'(1)`=tq(2020q3)' {;

di %tq `q';

#delimit ;
/* Load Data */
u "${revisiondata}/counterfactuals/counterfactuals_data.dta", clear;
keep if date==`q' & LNrweight_conditional<.;


/* Generate counterfactual variable */

/* We undo the size of ETFs by assuming they approx hold 0.1% of all the observed
   holdings --> same magnitude as they were back in 2006Q1 */
   
/* Merge AUM proportions from 2006Q1 */

qui merge m:1 type_new2 using "${revisiondata}/counterfactuals/proportions_aum_06Q1.dta";
drop _merge;

/* Dollars aum by investor group */
bysort date fundid: gen aum_fund = aum_tot if _n == 1;
replace aum_fund = 0 if aum_fund == .;
bysort type_new2: gegen aum_type = sum(aum_fund);
gegen tot_aum_obs = sum(aum_fund) if type_new2 != 0;
gen frac_aum_type = aum_tot/aum_type if type_new2 != 0;
gen proportion_aum_type_obs = aum_type/tot_aum_obs;

/* Counterfactual total aum by investor group */
gen aum_type_cf = aum_type/proportion_aum_type_obs*proportions_aum_obs_06Q1 if type_new2 == 5;

/* Assign difference in aum of ETFs to MFs */
gen diff_aum_type_etf = aum_type - aum_type_cf if type_new2 == 5;
gegen diff_aum_type_etf_all = mean(diff_aum_type_etf);
replace aum_type_cf = aum_type + diff_aum_type_etf_all if type_new2 == 3;

/* Counterfactual total aum by investor */
gen aum_tot_cf = aum_type_cf*frac_aum_type if type_new2 == 5;
replace aum_tot_cf = aum_type_cf*frac_aum_type if type_new2 == 3;

/* Counterfactual aum residual - stays the same (otherwise fraction observed would change!) */
replace aum_tot_cf = aum_tot if type_new2 <=2;
replace aum_tot_cf = aum_tot if type_new2 ==4;
replace aum_tot_cf = aum_tot if type_new2 >=6;


/* Impose downward sloping demand as in KY (2019) */
replace _b_ss_price_iv = 0.99 if _b_ss_price_iv >= 1; 

/* Initial guess for price */
gen ln_priceLoop = ln_mp;

/* Set characteristics */
gen LNtimetomatLoop = LNtimetomat;  
gen spreadLoop = spread;
gen LNbvLoop = LNbv; 
gen coupon_decLoop = coupon_dec; 
gen rating_numLoop = rating_num;  

/* Set AUM */
gen aumLoop = aum_tot_cf;

/* Calculate within credit rating group latent demand (epsilon) plus the constant */
gen const_eps = LNrweight_conditional - (_b_ss_price_iv*ln_mp + _b_ss_price_tmt*LNtimetomat + _b_ss_price_spread*spread + _b_ss_price_bv*LNbv + _b_ss_price_rating*rating_num + _b_ss_price_coupon*coupon_dec);

/* Calculate across credit rating group latent demand (xi) plus fixed effect (alpha) */
gen alpha_xi = LNweight_assetclass - (LNoutweight_conditional1*_b_LNoutweight_conditional1 +LNoutweight_conditional2*_b_LNoutweight_conditional2);

/* Alpha_xi is only defined for one credit rating group --> set to zero otherwise */
replace alpha_xi = 0 if assetclass == 2;
replace alpha_xi = 0 if exclusive == 1;


/* Set coefficients */
foreach var of varlist _b_ss_price_iv _b_ss_price_tmt _b_ss_price_spread _b_ss_price_bv _b_ss_price_rating _b_ss_price_coupon{;
	gen `var'Loop = `var';
	};

/* Set the latent variable for within credit rating group */
gen latent = _b_ss_price_tmtLoop*LNtimetomatLoop + _b_ss_price_spreadLoop*spreadLoop + _b_ss_price_bvLoop*LNbvLoop + _b_ss_price_ratingLoop*rating_numLoop + 
 _b_ss_price_couponLoop*coupon_decLoop + const_eps;


#delimit ;

/* Solve for price */
forval j = 1/500 {;
	
	#delimit ;
	
	/* Update within credit rating group weights */

	gen double delta = exp(_b_ss_price_ivLoop*ln_priceLoop+latent);
	gegen double sum_delta = sum(delta), by(date fundid assetclass);

	gen double weight_conditional = delta/(1+sum_delta);
	
	#delimit ;
	/* Update across credit rating group weights */
	
	gen double inclusive_value = 1+sum_delta;
	
	gen double numerator = ( (inclusive_value)^lambda )*exp(alpha_xi);
	
	gen double numerator_once = numerator;
	bysort date fundid assetclass: replace numerator_once = 0 if _n != 1;
	
	gegen double denominator = sum(numerator_once), by(date fundid);

    gen double weight_across = numerator/denominator;
	
	
	#delimit ;
	/* Update bond specific weights */

	gen double weight = weight_conditional*weight_across;
	
	gegen double demand = sum(aumLoop*weight), by(date bondid);
	
	gegen double Ddemand = sum(aumLoop*( lambda*_b_ss_price_ivLoop*weight_conditional*weight_across*(1-weight_across)*weight_conditional + _b_ss_price_ivLoop*weight_conditional*(1-weight_conditional)*weight_across )/demand), by(date bondid);
	replace Ddemand = 1/(1-min(0,Ddemand));

	drop delta sum_delta weight_conditional inclusive_value numerator numerator_once denominator weight_across weight;

	/* Check convergence - Market Clearing */

	gen gap = ln(demand)-ln_priceLoop-LNbvLoop;

	sum gap;
	local gap = max(abs(r(min)),abs(r(max)));

	/* Update price */

	replace ln_priceLoop = ln_priceLoop+Ddemand*gap;

	drop demand Ddemand gap;

	/* Exit if converged */

	if `j'==1000 | `gap'<10^-4 {;
		di `j' _skip(5) `gap';

		egen ln_mpCF = min(ln_priceLoop), by(bondid);
		gen gap = `gap';

		continue, break;
	};
};

#delimit ;
/* Construct variables */
sort date bondid fundid;
qui by date bondid: keep if _n==1;

/* Construct yield changes */
gen price_CF = exp(ln_mpCF)*100;
gen yield_CF = -ln_mpCF/timetomat;
gen CF_pc_yield = 100*(yield_CF - yield)/yield;
gen CF_chg_yield = 100*(yield_CF - yield);


save "${revisiondata}/counterfactuals/cf_six_`q'.dta", replace;


};



#delimit cr


/* -----------------------------------------------------------------------------

Counterfactual 9: MF sector same size as in 2006Q1 --> AUM goes to ETFs

-----------------------------------------------------------------------------*/

clear all
set more off

set varabbrev off

******************************************************************************
* Specify working directory
******************************************************************************

* For example
* cd "/Users/.../XYZ/"

global rawdata "Data/Raw_Data"
global tempdata "Data/RevisionRFS/temp_data"
global masterdata "Data/Master_Data"
global revisiondata "Data/RevisionRFS"
global revisionfigures = "Results/RevisionRFS/Figures"
global revisionoutput = "Results/RevisionRFS/Output"

clear all
set more off
set type double

#delimit ;

forval q = `=tq(2006q1)'(1)`=tq(2020q3)' {;

di %tq `q';

#delimit ;
/* Load Data */
u "${revisiondata}/counterfactuals/counterfactuals_data.dta", clear;
keep if date==`q' & LNrweight_conditional<.;


/* Generate counterfactual variable */

/* We undo the size of MFs by assuming they approx hold 1% of the market --> 
   compared to their actual 5% of the market in 2006Q1 */
   
/* Merge AUM proportions from 2006Q1 */

qui merge m:1 type_new2 using "${revisiondata}/counterfactuals/proportions_aum_06Q1.dta";
drop _merge;

/* Dollars aum by investor group */
bysort date fundid: gen aum_fund = aum_tot if _n == 1;
replace aum_fund = 0 if aum_fund == .;
bysort type_new2: gegen aum_type = sum(aum_fund);
gegen tot_aum_obs = sum(aum_fund) if type_new2 != 0;
gen frac_aum_type = aum_tot/aum_type if type_new2 != 0;
gen proportion_aum_type_obs = aum_type/tot_aum_obs;

/* Counterfactual total aum by investor group */
gen aum_type_cf = aum_type/proportion_aum_type_obs*proportions_aum_obs_06Q1 if type_new2 == 3;

/* Assign difference in aum of ETFs to MFs */
gen diff_aum_type_mf = aum_type - aum_type_cf if type_new2 == 3;
gegen diff_aum_type_mf_all = mean(diff_aum_type_mf);
replace aum_type_cf = aum_type + diff_aum_type_mf_all if type_new2 == 5;

/* Counterfactual total aum by investor */
gen aum_tot_cf = aum_type_cf*frac_aum_type if type_new2 == 3;
replace aum_tot_cf = aum_type_cf*frac_aum_type if type_new2 == 5;

/* Counterfactual aum residual - stays the same (otherwise fraction observed would change!) */
replace aum_tot_cf = aum_tot if type_new2 <=2;
replace aum_tot_cf = aum_tot if type_new2 ==4;
replace aum_tot_cf = aum_tot if type_new2 >=6;


/* Impose downward sloping demand as in KY (2019) */
replace _b_ss_price_iv = 0.99 if _b_ss_price_iv >= 1; 

/* Initial guess for price */
gen ln_priceLoop = ln_mp;

/* Set characteristics */
gen LNtimetomatLoop = LNtimetomat;  
gen spreadLoop = spread;
gen LNbvLoop = LNbv; 
gen coupon_decLoop = coupon_dec; 
gen rating_numLoop = rating_num;  

/* Set AUM */
gen aumLoop = aum_tot_cf;

/* Calculate within credit rating group latent demand (epsilon) plus the constant */
gen const_eps = LNrweight_conditional - (_b_ss_price_iv*ln_mp + _b_ss_price_tmt*LNtimetomat + _b_ss_price_spread*spread + _b_ss_price_bv*LNbv + _b_ss_price_rating*rating_num + _b_ss_price_coupon*coupon_dec);

/* Calculate across credit rating group latent demand (xi) plus fixed effect (alpha) */
gen alpha_xi = LNweight_assetclass - (LNoutweight_conditional1*_b_LNoutweight_conditional1 +LNoutweight_conditional2*_b_LNoutweight_conditional2);

/* Alpha_xi is only defined for one credit rating group --> set to zero otherwise */
replace alpha_xi = 0 if assetclass == 2;
replace alpha_xi = 0 if exclusive == 1;


/* Set coefficients */
foreach var of varlist _b_ss_price_iv _b_ss_price_tmt _b_ss_price_spread _b_ss_price_bv _b_ss_price_rating _b_ss_price_coupon{;
	gen `var'Loop = `var';
	};

/* Set the latent variable for within credit rating group */
gen latent = _b_ss_price_tmtLoop*LNtimetomatLoop + _b_ss_price_spreadLoop*spreadLoop + _b_ss_price_bvLoop*LNbvLoop + _b_ss_price_ratingLoop*rating_numLoop + 
 _b_ss_price_couponLoop*coupon_decLoop + const_eps;


#delimit ;

/* Solve for price */
forval j = 1/500 {;
	
	#delimit ;
	
	/* Update within credit rating group weights */

	gen double delta = exp(_b_ss_price_ivLoop*ln_priceLoop+latent);
	gegen double sum_delta = sum(delta), by(date fundid assetclass);

	gen double weight_conditional = delta/(1+sum_delta);
	
	#delimit ;
	/* Update across credit rating group weights */
	
	gen double inclusive_value = 1+sum_delta;
	
	gen double numerator = ( (inclusive_value)^lambda )*exp(alpha_xi);
	
	gen double numerator_once = numerator;
	bysort date fundid assetclass: replace numerator_once = 0 if _n != 1;
	
	gegen double denominator = sum(numerator_once), by(date fundid);

    gen double weight_across = numerator/denominator;
	
	
	#delimit ;
	/* Update bond specific weights */

	gen double weight = weight_conditional*weight_across;
	
	gegen double demand = sum(aumLoop*weight), by(date bondid);
	
	gegen double Ddemand = sum(aumLoop*( lambda*_b_ss_price_ivLoop*weight_conditional*weight_across*(1-weight_across)*weight_conditional + _b_ss_price_ivLoop*weight_conditional*(1-weight_conditional)*weight_across )/demand), by(date bondid);
	replace Ddemand = 1/(1-min(0,Ddemand));

	drop delta sum_delta weight_conditional inclusive_value numerator numerator_once denominator weight_across weight;

	/* Check convergence - Market Clearing */

	gen gap = ln(demand)-ln_priceLoop-LNbvLoop;

	sum gap;
	local gap = max(abs(r(min)),abs(r(max)));

	/* Update price */

	replace ln_priceLoop = ln_priceLoop+Ddemand*gap;

	drop demand Ddemand gap;

	/* Exit if converged */

	if `j'==1000 | `gap'<10^-4 {;
		di `j' _skip(5) `gap';

		egen ln_mpCF = min(ln_priceLoop), by(bondid);
		gen gap = `gap';

		continue, break;
	};
};

#delimit ;
/* Construct variables */
sort date bondid fundid;
qui by date bondid: keep if _n==1;

/* Construct yield changes */
gen price_CF = exp(ln_mpCF)*100;
gen yield_CF = -ln_mpCF/timetomat;
gen CF_pc_yield = 100*(yield_CF - yield)/yield;
gen CF_chg_yield = 100*(yield_CF - yield);


save "${revisiondata}/counterfactuals/cf_nine_`q'.dta", replace;


};



#delimit cr


/* -----------------------------------------------------------------------------

Counterfactual 13: MF and ETF sector have same size as in 2006Q1 - proportionally

-----------------------------------------------------------------------------*/

clear all
set more off

set varabbrev off

******************************************************************************
* Specify working directory
******************************************************************************

* For example
* cd "/Users/.../XYZ/"

global rawdata "Data/Raw_Data"
global tempdata "Data/RevisionRFS/temp_data"
global masterdata "Data/Master_Data"
global revisiondata "Data/RevisionRFS"
global revisionfigures = "Results/RevisionRFS/Figures"
global revisionoutput = "Results/RevisionRFS/Output"

clear all
set more off
set type double


/* Generate Proportions in 2006Q1 */
#delimit ;
u date fundid bondid type_new2 holding
	aum_tot
	if date==184
	using "${revisiondata}/counterfactuals/counterfactuals_data.dta", clear;

collapse aum_tot, by(type_new2 fundid);
gegen aum_tot_all = sum(aum_tot);
gen aum_fund_obs = aum_tot;
replace aum_fund_obs = 0 if type_new2 == 0;
gegen aum_tot_obs = sum(aum_fund_obs);
gegen aum_type = sum(aum_tot), by(type_new2);
gen frac_type_aum_obs = aum_type/aum_tot_obs if type_new2 != 0;

rename frac_type_aum_obs proportions_aum_obs_06Q1;
collapse proportions_aum_obs_06Q1, by(type_new2);

save "${revisiondata}/counterfactuals/proportions_aum_06Q1.dta", replace;


#delimit ;

forval q = `=tq(2006q1)'(1)`=tq(2020q3)' {;

di %tq `q';

#delimit ;
/* Load Data */
u "${revisiondata}/counterfactuals/counterfactuals_data.dta", clear;
keep if date==`q' & LNrweight_conditional<.;


/* Generate counterfactual variable */

/* Merge AUM proportions from 2006Q1 */

qui merge m:1 type_new2 using "${revisiondata}/counterfactuals/proportions_aum_06Q1.dta";
drop _merge;

/* Dollars aum by investor group */
bysort date fundid: gen aum_fund = aum_tot if _n == 1;
replace aum_fund = 0 if aum_fund == .;
bysort type_new2: gegen aum_type = sum(aum_fund);
gegen tot_aum_obs = sum(aum_fund) if type_new2 != 0;
gen frac_aum_mf = aum_tot/aum_type if type_new2 == 3;
gen frac_aum_etf = aum_tot/aum_type if type_new2 == 5;
gegen tot_aum_rest_obs = sum(aum_fund) if type_new2 != 3 & type_new2 != 5 & type_new2 != 0;
gen frac_tot_aum_rest_obs = aum_tot/tot_aum_rest_obs if type_new2 != 3 & type_new2 != 5 & type_new2 != 0;
gen proportion_aum_mf_obs = aum_type/tot_aum_obs if type_new2 == 3;
gen proportion_aum_etf_obs = aum_type/tot_aum_obs if type_new2 == 5;

/* Counterfactual total aum by investor group */
gen aum_mf_cf = aum_type/proportion_aum_mf_obs*proportions_aum_obs_06Q1 if type_new2 == 3;
gen aum_etf_cf = aum_type/proportion_aum_etf_obs*proportions_aum_obs_06Q1 if type_new2 == 5;
gegen aum_mf_cf_all = mean(aum_mf_cf);
gegen aum_etf_cf_all = mean(aum_etf_cf);
gen tot_aum_rest_obs_cf = tot_aum_obs - aum_mf_cf_all - aum_etf_cf_all;

/* Counterfactual total aum by investor */
gen aum_tot_cf = aum_mf_cf*frac_aum_mf if type_new2 == 3;
replace aum_tot_cf = aum_etf_cf*frac_aum_etf if type_new2 == 5;
replace aum_tot_cf = tot_aum_rest_obs_cf*frac_tot_aum_rest_obs if type_new2 != 3 & type_new2 != 5 & type_new2 != 0;

/* Counterfactual aum residual - stays the same (otherwise fraction observed would change!) */
replace aum_tot_cf = aum_tot if type_new2 == 0;


/* Impose downward sloping demand as in KY (2019) */
replace _b_ss_price_iv = 0.99 if _b_ss_price_iv >= 1; 

/* Initial guess for price */
gen ln_priceLoop = ln_mp;

/* Set characteristics */
gen LNtimetomatLoop = LNtimetomat;  
gen spreadLoop = spread;
gen LNbvLoop = LNbv; 
gen coupon_decLoop = coupon_dec; 
gen rating_numLoop = rating_num;  

/* Set AUM */
gen aumLoop = aum_tot_cf;

/* Calculate within credit rating group latent demand (epsilon) plus the constant */
gen const_eps = LNrweight_conditional - (_b_ss_price_iv*ln_mp + _b_ss_price_tmt*LNtimetomat + _b_ss_price_spread*spread + _b_ss_price_bv*LNbv + _b_ss_price_rating*rating_num + _b_ss_price_coupon*coupon_dec);

/* Calculate across credit rating group latent demand (xi) plus fixed effect (alpha) */
gen alpha_xi = LNweight_assetclass - (LNoutweight_conditional1*_b_LNoutweight_conditional1 +LNoutweight_conditional2*_b_LNoutweight_conditional2);

/* Alpha_xi is only defined for one credit rating group --> set to zero otherwise */
replace alpha_xi = 0 if assetclass == 2;
replace alpha_xi = 0 if exclusive == 1;


/* Set coefficients */
foreach var of varlist _b_ss_price_iv _b_ss_price_tmt _b_ss_price_spread _b_ss_price_bv _b_ss_price_rating _b_ss_price_coupon{;
	gen `var'Loop = `var';
	};

/* Set the latent variable for within credit rating group */
gen latent = _b_ss_price_tmtLoop*LNtimetomatLoop + _b_ss_price_spreadLoop*spreadLoop + _b_ss_price_bvLoop*LNbvLoop + _b_ss_price_ratingLoop*rating_numLoop + 
 _b_ss_price_couponLoop*coupon_decLoop + const_eps;


#delimit ;

/* Solve for price */
forval j = 1/500 {;
	
	#delimit ;
	
	/* Update within credit rating group weights */

	gen double delta = exp(_b_ss_price_ivLoop*ln_priceLoop+latent);
	gegen double sum_delta = sum(delta), by(date fundid assetclass);

	gen double weight_conditional = delta/(1+sum_delta);
	
	#delimit ;
	/* Update across credit rating group weights */
	
	gen double inclusive_value = 1+sum_delta;
	
	gen double numerator = ( (inclusive_value)^lambda )*exp(alpha_xi);
	
	gen double numerator_once = numerator;
	bysort date fundid assetclass: replace numerator_once = 0 if _n != 1;
	
	gegen double denominator = sum(numerator_once), by(date fundid);

    gen double weight_across = numerator/denominator;
	
	
	#delimit ;
	/* Update bond specific weights */

	gen double weight = weight_conditional*weight_across;
	
	gegen double demand = sum(aumLoop*weight), by(date bondid);
	
	gegen double Ddemand = sum(aumLoop*( lambda*_b_ss_price_ivLoop*weight_conditional*weight_across*(1-weight_across)*weight_conditional + _b_ss_price_ivLoop*weight_conditional*(1-weight_conditional)*weight_across )/demand), by(date bondid);
	replace Ddemand = 1/(1-min(0,Ddemand));

	drop delta sum_delta weight_conditional inclusive_value numerator numerator_once denominator weight_across weight;

	/* Check convergence - Market Clearing */

	gen gap = ln(demand)-ln_priceLoop-LNbvLoop;

	sum gap;
	local gap = max(abs(r(min)),abs(r(max)));

	/* Update price */

	replace ln_priceLoop = ln_priceLoop+Ddemand*gap;

	drop demand Ddemand gap;

	/* Exit if converged */

	if `j'==1000 | `gap'<10^-4 {;
		di `j' _skip(5) `gap';

		egen ln_mpCF = min(ln_priceLoop), by(bondid);
		gen gap = `gap';

		continue, break;
	};
};

#delimit ;
/* Construct variables */
sort date bondid fundid;
qui by date bondid: keep if _n==1;

/* Construct yield changes */
gen price_CF = exp(ln_mpCF)*100;
gen yield_CF = -ln_mpCF/timetomat;
gen CF_pc_yield = 100*(yield_CF - yield)/yield;
gen CF_chg_yield = 100*(yield_CF - yield);


save "${revisiondata}/counterfactuals/cf_thirteen_`q'.dta", replace;


};



#delimit cr

/* -----------------------------------------------------------------------------

YES Define largest active MF and ETFs

------------------------------------------------------------------------------*/


/* Define largest MFs that together represent 5% (vis-a-vis observed market) */
#delimit ;
forval q = `=tq(2006q1)'(1)`=tq(2020q3)' {;

di %tq `q';
#delimit ;
u date fundid bondid type_new2 holding aum_tot LNrweight_conditional 
	if date==`q' & LNrweight_conditional<.
	using "${revisiondata}/counterfactuals/counterfactuals_data.dta", clear;

sort fundid;
qui by fundid: gen aum1 = aum_tot if _n == 1;
drop if aum1 ==.;
egen tot_sum_aum1 = sum(aum1);
keep if type_new2 == 3;
gsort -aum1 fundid;
egen sum_aum1 = sum(aum1);
gen mf_holdings_vs_tot = sum_aum1/tot_sum_aum1;

gen per_aum1 = aum1/tot_sum_aum1;
gen cumsum_per_aum1 = sum(per_aum1);
gen large_mf = 0;
replace large_mf = 1 if type_new2 == 3 & round(cumsum_per_aum1,0.001) <= 0.04;

keep if large_mf == 1;
keep date fundid large_mf mf_holdings_vs_tot;

save "${revisiondata}/counterfactuals/Large_mf_`q'.dta", replace;
};

#delimit ;
use "${revisiondata}/counterfactuals/Large_mf_184.dta", clear;
forval q = `=tq(2006q2)'(1)`=tq(2020q3)' {;

	append using "${revisiondata}/counterfactuals/Large_mf_`q'.dta";
};

keep if large_mf == 1;
keep date fundid large_mf mf_holdings_vs_tot;

save "${revisiondata}/counterfactuals/Large_mf.dta", replace;




/* Define largest ETFs that together represent 5% (vis-a-vis observed market) */
#delimit ;
forval q = `=tq(2006q1)'(1)`=tq(2020q3)' {;

di %tq `q';
#delimit ;
u date fundid bondid type_new2 holding aum_tot LNrweight_conditional 
	if date==`q' & LNrweight_conditional<.
	using "${revisiondata}/counterfactuals/counterfactuals_data.dta", clear;

sort fundid;
qui by fundid: gen aum1 = aum_tot if _n == 1;
drop if aum1 ==.;
egen tot_sum_aum1 = sum(aum1);
keep if type_new2 == 5;
gsort -aum1 fundid;
egen sum_aum1 = sum(aum1);
gen etf_holdings_vs_tot = sum_aum1/tot_sum_aum1;

gen per_aum1 = aum1/tot_sum_aum1;
gen cumsum_per_aum1 = sum(per_aum1);
gen large_etf = 0;
replace large_etf = 1 if type_new2 == 5 & round(cumsum_per_aum1,0.001) <= 0.04;

keep if large_etf == 1;
keep date fundid large_etf etf_holdings_vs_tot;

save "${revisiondata}/counterfactuals/Large_etf_`q'.dta", replace;
};

#delimit ;
use "${revisiondata}/counterfactuals/Large_etf_184.dta", clear;
forval q = `=tq(2006q2)'(1)`=tq(2020q3)' {;

	append using "${revisiondata}/counterfactuals/Large_etf_`q'.dta";
};

keep if large_etf == 1;
keep date fundid large_etf etf_holdings_vs_tot;

save "${revisiondata}/counterfactuals/Large_etf.dta", replace;





/* -----------------------------------------------------------------------------

Counterfactual 14: Run on largest active MF - other active MF absorb 

------------------------------------------------------------------------------*/

clear all
set more off

set varabbrev off

******************************************************************************
* Specify working directory
******************************************************************************

* For example
* cd "/Users/.../XYZ/"

global rawdata "Data/Raw_Data"
global tempdata "Data/RevisionRFS/temp_data"
global masterdata "Data/Master_Data"
global revisiondata "Data/RevisionRFS"
global revisionfigures = "Results/RevisionRFS/Figures"
global revisionoutput = "Results/RevisionRFS/Output"

clear all
set more off
set type double

#delimit ;

forval q = `=tq(2006q1)'(1)`=tq(2020q3)' {;

di %tq `q';

use "${revisiondata}/counterfactuals/Large_mf.dta", clear;

keep if date==`q';

if mf_holdings_vs_tot > 0.04{;

#delimit ;
/* Load Data */
u "${revisiondata}/counterfactuals/counterfactuals_data.dta", clear;
keep if date==`q' & LNrweight_conditional<.;


/* Generate counterfactual variable */
qui merge m:1 date fundid using "${revisiondata}/counterfactuals/Large_mf.dta";
drop if _merge == 2;
drop _merge;
replace large_mf = 0 if large_mf ==.;

/* Dollars aum by investor group */
bysort date fundid: gen aum_fund = aum_tot if _n == 1;
replace aum_fund = 0 if aum_fund == .;
bysort type_new2 large_mf: gegen aum_type = sum(aum_fund);
gegen tot_aum_obs = sum(aum_fund) if type_new2 != 0;
gen frac_aum_type = aum_tot/aum_type if type_new2 != 0;

/* Counterfactual total aum for all large MFs */
gen aum_type_cf = aum_type*0.5 if type_new2 == 3 & large_mf == 1;

/* Assign difference in aum of large MFs to other MFs */
gen diff_aum_type_mf = aum_type - aum_type_cf if type_new2 == 3 & large_mf == 1;
gegen diff_aum_type_mf_all = mean(diff_aum_type_mf);
replace aum_type_cf = aum_type + diff_aum_type_mf_all if type_new2 == 3 & large_mf == 0;

/* Counterfactual total aum by investor */
gen aum_tot_cf = aum_type_cf*frac_aum_type if type_new2 == 3;

/* Counterfactual aum residual - stays the same (otherwise fraction observed would change!) */
replace aum_tot_cf = aum_tot if type_new2 <=2;
replace aum_tot_cf = aum_tot if type_new2 >=4;


/* Impose downward sloping demand as in KY (2019) */
replace _b_ss_price_iv = 0.99 if _b_ss_price_iv >= 1; 

/* Initial guess for price */
gen ln_priceLoop = ln_mp;

/* Set characteristics */
gen LNtimetomatLoop = LNtimetomat;  
gen spreadLoop = spread;
gen LNbvLoop = LNbv; 
gen coupon_decLoop = coupon_dec; 
gen rating_numLoop = rating_num;  

/* Set AUM */
gen aumLoop = aum_tot_cf;

/* Calculate within credit rating group latent demand (epsilon) plus the constant */
gen const_eps = LNrweight_conditional - (_b_ss_price_iv*ln_mp + _b_ss_price_tmt*LNtimetomat + _b_ss_price_spread*spread + _b_ss_price_bv*LNbv + _b_ss_price_rating*rating_num + _b_ss_price_coupon*coupon_dec);

/* Calculate across credit rating group latent demand (xi) plus fixed effect (alpha) */
gen alpha_xi = LNweight_assetclass - (LNoutweight_conditional1*_b_LNoutweight_conditional1 +LNoutweight_conditional2*_b_LNoutweight_conditional2);

/* Alpha_xi is only defined for one credit rating group --> set to zero otherwise */
replace alpha_xi = 0 if assetclass == 2;
replace alpha_xi = 0 if exclusive == 1;


/* Set coefficients */
foreach var of varlist _b_ss_price_iv _b_ss_price_tmt _b_ss_price_spread _b_ss_price_bv _b_ss_price_rating _b_ss_price_coupon{;
	gen `var'Loop = `var';
	};

/* Set the latent variable for within credit rating group */
gen latent = _b_ss_price_tmtLoop*LNtimetomatLoop + _b_ss_price_spreadLoop*spreadLoop + _b_ss_price_bvLoop*LNbvLoop + _b_ss_price_ratingLoop*rating_numLoop + 
 _b_ss_price_couponLoop*coupon_decLoop + const_eps;


#delimit ;

/* Solve for price */
forval j = 1/500 {;
	
	#delimit ;
	
	/* Update within credit rating group weights */

	gen double delta = exp(_b_ss_price_ivLoop*ln_priceLoop+latent);
	gegen double sum_delta = sum(delta), by(date fundid assetclass);

	gen double weight_conditional = delta/(1+sum_delta);
	
	#delimit ;
	/* Update across credit rating group weights */
	
	gen double inclusive_value = 1+sum_delta;
	
	gen double numerator = ( (inclusive_value)^lambda )*exp(alpha_xi);
	
	gen double numerator_once = numerator;
	bysort date fundid assetclass: replace numerator_once = 0 if _n != 1;
	
	gegen double denominator = sum(numerator_once), by(date fundid);

    gen double weight_across = numerator/denominator;
	
	
	#delimit ;
	/* Update bond specific weights */

	gen double weight = weight_conditional*weight_across;
	
	gegen double demand = sum(aumLoop*weight), by(date bondid);
	
	gegen double Ddemand = sum(aumLoop*( lambda*_b_ss_price_ivLoop*weight_conditional*weight_across*(1-weight_across)*weight_conditional + _b_ss_price_ivLoop*weight_conditional*(1-weight_conditional)*weight_across )/demand), by(date bondid);
	replace Ddemand = 1/(1-min(0,Ddemand));

	drop delta sum_delta weight_conditional inclusive_value numerator numerator_once denominator weight_across weight;

	/* Check convergence - Market Clearing */

	gen gap = ln(demand)-ln_priceLoop-LNbvLoop;

	sum gap;
	local gap = max(abs(r(min)),abs(r(max)));

	/* Update price */

	replace ln_priceLoop = ln_priceLoop+Ddemand*gap;

	drop demand Ddemand gap;

	/* Exit if converged */

	if `j'==1000 | `gap'<10^-4 {;
		di `j' _skip(5) `gap';

		egen ln_mpCF = min(ln_priceLoop), by(bondid);
		gen gap = `gap';

		continue, break;
	};
};

#delimit ;
/* Construct variables */
sort date bondid fundid;
qui by date bondid: keep if _n==1;

/* Construct yield changes */
gen price_CF = exp(ln_mpCF)*100;
gen yield_CF = -ln_mpCF/timetomat;
gen CF_pc_yield = 100*(yield_CF - yield)/yield;
gen CF_chg_yield = 100*(yield_CF - yield);


save "${revisiondata}/counterfactuals/cf_fourteen_`q'.dta", replace;


};
};

#delimit cr



/* -----------------------------------------------------------------------------

Counterfactual 15: Run on largest active MF - ETFs absorb 

------------------------------------------------------------------------------*/


clear all
set more off

set varabbrev off

******************************************************************************
* Specify working directory
******************************************************************************

* For example
* cd "/Users/.../XYZ/"

global rawdata "Data/Raw_Data"
global tempdata "Data/RevisionRFS/temp_data"
global masterdata "Data/Master_Data"
global revisiondata "Data/RevisionRFS"
global revisionfigures = "Results/RevisionRFS/Figures"
global revisionoutput = "Results/RevisionRFS/Output"

clear all
set more off
set type double

#delimit ;

forval q = `=tq(2006q1)'(1)`=tq(2020q3)' {;

di %tq `q';

use "${revisiondata}/counterfactuals/Large_mf.dta", clear;

keep if date==`q';

if mf_holdings_vs_tot > 0.04{;

#delimit ;
/* Load Data */
u "${revisiondata}/counterfactuals/counterfactuals_data.dta", clear;
keep if date==`q' & LNrweight_conditional<.;


/* Generate counterfactual variable */
qui merge m:1 date fundid using "${revisiondata}/counterfactuals/Large_mf.dta";
drop if _merge == 2;
drop _merge;
replace large_mf = 0 if large_mf ==.;

/* Dollars aum by investor group */
bysort date fundid: gen aum_fund = aum_tot if _n == 1;
replace aum_fund = 0 if aum_fund == .;
bysort type_new2 large_mf: gegen aum_type = sum(aum_fund);
gegen tot_aum_obs = sum(aum_fund) if type_new2 != 0;
gen frac_aum_type = aum_tot/aum_type if type_new2 != 0;

/* Counterfactual total aum for all large MFs */
gen aum_type_cf = aum_type*0.5 if type_new2 == 3 & large_mf == 1;

/* Assign difference in aum of large MFs to other MFs */
gen diff_aum_type_mf = aum_type - aum_type_cf if type_new2 == 3 & large_mf == 1;
gegen diff_aum_type_mf_all = mean(diff_aum_type_mf);
replace aum_type_cf = aum_type + diff_aum_type_mf_all if type_new2 == 5;

/* Counterfactual total aum by investor */
gen aum_tot_cf = aum_type_cf*frac_aum_type if type_new2 == 3 & large_mf == 1;
replace aum_tot_cf = aum_type_cf*frac_aum_type if type_new2 == 5;
replace aum_tot_cf = aum_tot if type_new2 == 3 & large_mf == 0;

/* Counterfactual aum residual - stays the same (otherwise fraction observed would change!) */
replace aum_tot_cf = aum_tot if type_new2 <=2;
replace aum_tot_cf = aum_tot if type_new2 ==4;
replace aum_tot_cf = aum_tot if type_new2 >=6;

/* Impose downward sloping demand as in KY (2019) */
replace _b_ss_price_iv = 0.99 if _b_ss_price_iv >= 1; 

/* Initial guess for price */
gen ln_priceLoop = ln_mp;

/* Set characteristics */
gen LNtimetomatLoop = LNtimetomat;  
gen spreadLoop = spread;
gen LNbvLoop = LNbv; 
gen coupon_decLoop = coupon_dec; 
gen rating_numLoop = rating_num;  

/* Set AUM */
gen aumLoop = aum_tot_cf;

/* Calculate within credit rating group latent demand (epsilon) plus the constant */
gen const_eps = LNrweight_conditional - (_b_ss_price_iv*ln_mp + _b_ss_price_tmt*LNtimetomat + _b_ss_price_spread*spread + _b_ss_price_bv*LNbv + _b_ss_price_rating*rating_num + _b_ss_price_coupon*coupon_dec);

/* Calculate across credit rating group latent demand (xi) plus fixed effect (alpha) */
gen alpha_xi = LNweight_assetclass - (LNoutweight_conditional1*_b_LNoutweight_conditional1 +LNoutweight_conditional2*_b_LNoutweight_conditional2);

/* Alpha_xi is only defined for one credit rating group --> set to zero otherwise */
replace alpha_xi = 0 if assetclass == 2;
replace alpha_xi = 0 if exclusive == 1;


/* Set coefficients */
foreach var of varlist _b_ss_price_iv _b_ss_price_tmt _b_ss_price_spread _b_ss_price_bv _b_ss_price_rating _b_ss_price_coupon{;
	gen `var'Loop = `var';
	};

/* Set the latent variable for within credit rating group */
gen latent = _b_ss_price_tmtLoop*LNtimetomatLoop + _b_ss_price_spreadLoop*spreadLoop + _b_ss_price_bvLoop*LNbvLoop + _b_ss_price_ratingLoop*rating_numLoop + 
 _b_ss_price_couponLoop*coupon_decLoop + const_eps;


#delimit ;

/* Solve for price */
forval j = 1/500 {;
	
	#delimit ;
	
	/* Update within credit rating group weights */

	gen double delta = exp(_b_ss_price_ivLoop*ln_priceLoop+latent);
	gegen double sum_delta = sum(delta), by(date fundid assetclass);

	gen double weight_conditional = delta/(1+sum_delta);
	
	#delimit ;
	/* Update across credit rating group weights */
	
	gen double inclusive_value = 1+sum_delta;
	
	gen double numerator = ( (inclusive_value)^lambda )*exp(alpha_xi);
	
	gen double numerator_once = numerator;
	bysort date fundid assetclass: replace numerator_once = 0 if _n != 1;
	
	gegen double denominator = sum(numerator_once), by(date fundid);

    gen double weight_across = numerator/denominator;
	
	
	#delimit ;
	/* Update bond specific weights */

	gen double weight = weight_conditional*weight_across;
	
	gegen double demand = sum(aumLoop*weight), by(date bondid);
	
	gegen double Ddemand = sum(aumLoop*( lambda*_b_ss_price_ivLoop*weight_conditional*weight_across*(1-weight_across)*weight_conditional + _b_ss_price_ivLoop*weight_conditional*(1-weight_conditional)*weight_across )/demand), by(date bondid);
	replace Ddemand = 1/(1-min(0,Ddemand));

	drop delta sum_delta weight_conditional inclusive_value numerator numerator_once denominator weight_across weight;

	/* Check convergence - Market Clearing */

	gen gap = ln(demand)-ln_priceLoop-LNbvLoop;

	sum gap;
	local gap = max(abs(r(min)),abs(r(max)));

	/* Update price */

	replace ln_priceLoop = ln_priceLoop+Ddemand*gap;

	drop demand Ddemand gap;

	/* Exit if converged */

	if `j'==1000 | `gap'<10^-4 {;
		di `j' _skip(5) `gap';

		egen ln_mpCF = min(ln_priceLoop), by(bondid);
		gen gap = `gap';

		continue, break;
	};
};

#delimit ;
/* Construct variables */
sort date bondid fundid;
qui by date bondid: keep if _n==1;

/* Construct yield changes */
gen price_CF = exp(ln_mpCF)*100;
gen yield_CF = -ln_mpCF/timetomat;
gen CF_pc_yield = 100*(yield_CF - yield)/yield;
gen CF_chg_yield = 100*(yield_CF - yield);


save "${revisiondata}/counterfactuals/cf_fifteen_`q'.dta", replace;


};
};

#delimit cr




/* -----------------------------------------------------------------------------

Counterfactual 16: Run on largest active MF - Life insurers absorb 

------------------------------------------------------------------------------*/


clear all
set more off

set varabbrev off

******************************************************************************
* Specify working directory
******************************************************************************

* For example
* cd "/Users/.../XYZ/"

global rawdata "Data/Raw_Data"
global tempdata "Data/RevisionRFS/temp_data"
global masterdata "Data/Master_Data"
global revisiondata "Data/RevisionRFS"
global revisionfigures = "Results/RevisionRFS/Figures"
global revisionoutput = "Results/RevisionRFS/Output"

clear all
set more off
set type double

#delimit ;

forval q = `=tq(2006q1)'(1)`=tq(2020q3)' {;

di %tq `q';

use "${revisiondata}/counterfactuals/Large_mf.dta", clear;

keep if date==`q';

if mf_holdings_vs_tot > 0.04{;

#delimit ;
/* Load Data */
u "${revisiondata}/counterfactuals/counterfactuals_data.dta", clear;
keep if date==`q' & LNrweight_conditional<.;


/* Generate counterfactual variable */
qui merge m:1 date fundid using "${revisiondata}/counterfactuals/Large_mf.dta";
drop if _merge == 2;
drop _merge;
replace large_mf = 0 if large_mf ==.;

/* Dollars aum by investor group */
bysort date fundid: gen aum_fund = aum_tot if _n == 1;
replace aum_fund = 0 if aum_fund == .;
bysort type_new2 large_mf: gegen aum_type = sum(aum_fund);
gegen tot_aum_obs = sum(aum_fund) if type_new2 != 0;
gen frac_aum_type = aum_tot/aum_type if type_new2 != 0;

/* Counterfactual total aum for all large MFs */
gen aum_type_cf = aum_type*0.5 if type_new2 == 3 & large_mf == 1;

/* Assign difference in aum of large MFs to other MFs */
gen diff_aum_type_mf = aum_type - aum_type_cf if type_new2 == 3 & large_mf == 1;
gegen diff_aum_type_mf_all = mean(diff_aum_type_mf);
replace aum_type_cf = aum_type + diff_aum_type_mf_all if type_new2 == 1;

/* Counterfactual total aum by investor */
gen aum_tot_cf = aum_type_cf*frac_aum_type if type_new2 == 3 & large_mf == 1;
replace aum_tot_cf = aum_type_cf*frac_aum_type if type_new2 == 1;
replace aum_tot_cf = aum_tot if type_new2 == 3 & large_mf == 0;

/* Counterfactual aum residual - stays the same (otherwise fraction observed would change!) */
replace aum_tot_cf = aum_tot if type_new2 ==0;
replace aum_tot_cf = aum_tot if type_new2 ==2;
replace aum_tot_cf = aum_tot if type_new2 >=4;


/* Impose downward sloping demand as in KY (2019) */
replace _b_ss_price_iv = 0.99 if _b_ss_price_iv >= 1; 

/* Initial guess for price */
gen ln_priceLoop = ln_mp;

/* Set characteristics */
gen LNtimetomatLoop = LNtimetomat;  
gen spreadLoop = spread;
gen LNbvLoop = LNbv; 
gen coupon_decLoop = coupon_dec; 
gen rating_numLoop = rating_num;  

/* Set AUM */
gen aumLoop = aum_tot_cf;

/* Calculate within credit rating group latent demand (epsilon) plus the constant */
gen const_eps = LNrweight_conditional - (_b_ss_price_iv*ln_mp + _b_ss_price_tmt*LNtimetomat + _b_ss_price_spread*spread + _b_ss_price_bv*LNbv + _b_ss_price_rating*rating_num + _b_ss_price_coupon*coupon_dec);

/* Calculate across credit rating group latent demand (xi) plus fixed effect (alpha) */
gen alpha_xi = LNweight_assetclass - (LNoutweight_conditional1*_b_LNoutweight_conditional1 +LNoutweight_conditional2*_b_LNoutweight_conditional2);

/* Alpha_xi is only defined for one credit rating group --> set to zero otherwise */
replace alpha_xi = 0 if assetclass == 2;
replace alpha_xi = 0 if exclusive == 1;


/* Set coefficients */
foreach var of varlist _b_ss_price_iv _b_ss_price_tmt _b_ss_price_spread _b_ss_price_bv _b_ss_price_rating _b_ss_price_coupon{;
	gen `var'Loop = `var';
	};

/* Set the latent variable for within credit rating group */
gen latent = _b_ss_price_tmtLoop*LNtimetomatLoop + _b_ss_price_spreadLoop*spreadLoop + _b_ss_price_bvLoop*LNbvLoop + _b_ss_price_ratingLoop*rating_numLoop + 
 _b_ss_price_couponLoop*coupon_decLoop + const_eps;


#delimit ;

/* Solve for price */
forval j = 1/500 {;
	
	#delimit ;
	
	/* Update within credit rating group weights */

	gen double delta = exp(_b_ss_price_ivLoop*ln_priceLoop+latent);
	gegen double sum_delta = sum(delta), by(date fundid assetclass);

	gen double weight_conditional = delta/(1+sum_delta);
	
	#delimit ;
	/* Update across credit rating group weights */
	
	gen double inclusive_value = 1+sum_delta;
	
	gen double numerator = ( (inclusive_value)^lambda )*exp(alpha_xi);
	
	gen double numerator_once = numerator;
	bysort date fundid assetclass: replace numerator_once = 0 if _n != 1;
	
	gegen double denominator = sum(numerator_once), by(date fundid);

    gen double weight_across = numerator/denominator;
	
	
	#delimit ;
	/* Update bond specific weights */

	gen double weight = weight_conditional*weight_across;
	
	gegen double demand = sum(aumLoop*weight), by(date bondid);
	
	gegen double Ddemand = sum(aumLoop*( lambda*_b_ss_price_ivLoop*weight_conditional*weight_across*(1-weight_across)*weight_conditional + _b_ss_price_ivLoop*weight_conditional*(1-weight_conditional)*weight_across )/demand), by(date bondid);
	replace Ddemand = 1/(1-min(0,Ddemand));

	drop delta sum_delta weight_conditional inclusive_value numerator numerator_once denominator weight_across weight;

	/* Check convergence - Market Clearing */

	gen gap = ln(demand)-ln_priceLoop-LNbvLoop;

	sum gap;
	local gap = max(abs(r(min)),abs(r(max)));

	/* Update price */

	replace ln_priceLoop = ln_priceLoop+Ddemand*gap;

	drop demand Ddemand gap;

	/* Exit if converged */

	if `j'==1000 | `gap'<10^-4 {;
		di `j' _skip(5) `gap';

		egen ln_mpCF = min(ln_priceLoop), by(bondid);
		gen gap = `gap';

		continue, break;
	};
};

#delimit ;
/* Construct variables */
sort date bondid fundid;
qui by date bondid: keep if _n==1;

/* Construct yield changes */
gen price_CF = exp(ln_mpCF)*100;
gen yield_CF = -ln_mpCF/timetomat;
gen CF_pc_yield = 100*(yield_CF - yield)/yield;
gen CF_chg_yield = 100*(yield_CF - yield);


save "${revisiondata}/counterfactuals/cf_sixteen_`q'.dta", replace;


};
};

#delimit cr




/* -----------------------------------------------------------------------------

Counterfactual 17: Run on largest ETFs - active MF absorb 

------------------------------------------------------------------------------*/

clear all
set more off

set varabbrev off

******************************************************************************
* Specify working directory
******************************************************************************

* For example
* cd "/Users/.../XYZ/"

global rawdata "Data/Raw_Data"
global tempdata "Data/RevisionRFS/temp_data"
global masterdata "Data/Master_Data"
global revisiondata "Data/RevisionRFS"
global revisionfigures = "Results/RevisionRFS/Figures"
global revisionoutput = "Results/RevisionRFS/Output"

clear all
set more off
set type double

#delimit ;

forval q = `=tq(2006q1)'(1)`=tq(2020q3)' {;

di %tq `q';

use "${revisiondata}/counterfactuals/Large_etf.dta", clear;

keep if date==`q';

if etf_holdings_vs_tot > 0.04{;

#delimit ;
/* Load Data */
u "${revisiondata}/counterfactuals/counterfactuals_data.dta", clear;
keep if date==`q' & LNrweight_conditional<.;


/* Generate counterfactual variable */
qui merge m:1 date fundid using "${revisiondata}/counterfactuals/Large_etf.dta";
drop if _merge == 2;
drop _merge;
replace large_etf = 0 if large_etf ==.;

/* Dollars aum by investor group */
bysort date fundid: gen aum_fund = aum_tot if _n == 1;
replace aum_fund = 0 if aum_fund == .;
bysort type_new2 large_etf: gegen aum_type = sum(aum_fund);
gegen tot_aum_obs = sum(aum_fund) if type_new2 != 0;
gen frac_aum_type = aum_tot/aum_type if type_new2 != 0;

/* Counterfactual total aum for all large MFs */
gen aum_type_cf = aum_type*0.5 if type_new2 == 5 & large_etf == 1;

/* Assign difference in aum of large MFs to other MFs */
gen diff_aum_type_etf = aum_type - aum_type_cf if type_new2 == 5 & large_etf == 1;
gegen diff_aum_type_etf_all = mean(diff_aum_type_etf);
replace aum_type_cf = aum_type + diff_aum_type_etf_all if type_new2 == 3;

/* Counterfactual total aum by investor */
gen aum_tot_cf = aum_type_cf*frac_aum_type if type_new2 == 5 & large_etf == 1;
replace aum_tot_cf = aum_tot if type_new2 == 5 & large_etf == 0;
replace aum_tot_cf = aum_type_cf*frac_aum_type if type_new2 == 3;

/* Counterfactual aum residual - stays the same (otherwise fraction observed would change!) */
replace aum_tot_cf = aum_tot if type_new2 <=2;
replace aum_tot_cf = aum_tot if type_new2 ==4;
replace aum_tot_cf = aum_tot if type_new2 >=6;

/* Impose downward sloping demand as in KY (2019) */
replace _b_ss_price_iv = 0.99 if _b_ss_price_iv >= 1; 

/* Initial guess for price */
gen ln_priceLoop = ln_mp;

/* Set characteristics */
gen LNtimetomatLoop = LNtimetomat;  
gen spreadLoop = spread;
gen LNbvLoop = LNbv; 
gen coupon_decLoop = coupon_dec; 
gen rating_numLoop = rating_num;  

/* Set AUM */
gen aumLoop = aum_tot_cf;

/* Calculate within credit rating group latent demand (epsilon) plus the constant */
gen const_eps = LNrweight_conditional - (_b_ss_price_iv*ln_mp + _b_ss_price_tmt*LNtimetomat + _b_ss_price_spread*spread + _b_ss_price_bv*LNbv + _b_ss_price_rating*rating_num + _b_ss_price_coupon*coupon_dec);

/* Calculate across credit rating group latent demand (xi) plus fixed effect (alpha) */
gen alpha_xi = LNweight_assetclass - (LNoutweight_conditional1*_b_LNoutweight_conditional1 +LNoutweight_conditional2*_b_LNoutweight_conditional2);

/* Alpha_xi is only defined for one credit rating group --> set to zero otherwise */
replace alpha_xi = 0 if assetclass == 2;
replace alpha_xi = 0 if exclusive == 1;


/* Set coefficients */
foreach var of varlist _b_ss_price_iv _b_ss_price_tmt _b_ss_price_spread _b_ss_price_bv _b_ss_price_rating _b_ss_price_coupon{;
	gen `var'Loop = `var';
	};

/* Set the latent variable for within credit rating group */
gen latent = _b_ss_price_tmtLoop*LNtimetomatLoop + _b_ss_price_spreadLoop*spreadLoop + _b_ss_price_bvLoop*LNbvLoop + _b_ss_price_ratingLoop*rating_numLoop + 
 _b_ss_price_couponLoop*coupon_decLoop + const_eps;


#delimit ;

/* Solve for price */
forval j = 1/500 {;
	
	#delimit ;
	
	/* Update within credit rating group weights */

	gen double delta = exp(_b_ss_price_ivLoop*ln_priceLoop+latent);
	gegen double sum_delta = sum(delta), by(date fundid assetclass);

	gen double weight_conditional = delta/(1+sum_delta);
	
	#delimit ;
	/* Update across credit rating group weights */
	
	gen double inclusive_value = 1+sum_delta;
	
	gen double numerator = ( (inclusive_value)^lambda )*exp(alpha_xi);
	
	gen double numerator_once = numerator;
	bysort date fundid assetclass: replace numerator_once = 0 if _n != 1;
	
	gegen double denominator = sum(numerator_once), by(date fundid);

    gen double weight_across = numerator/denominator;
	
	
	#delimit ;
	/* Update bond specific weights */

	gen double weight = weight_conditional*weight_across;
	
	gegen double demand = sum(aumLoop*weight), by(date bondid);
	
	gegen double Ddemand = sum(aumLoop*( lambda*_b_ss_price_ivLoop*weight_conditional*weight_across*(1-weight_across)*weight_conditional + _b_ss_price_ivLoop*weight_conditional*(1-weight_conditional)*weight_across )/demand), by(date bondid);
	replace Ddemand = 1/(1-min(0,Ddemand));

	drop delta sum_delta weight_conditional inclusive_value numerator numerator_once denominator weight_across weight;

	/* Check convergence - Market Clearing */

	gen gap = ln(demand)-ln_priceLoop-LNbvLoop;

	sum gap;
	local gap = max(abs(r(min)),abs(r(max)));

	/* Update price */

	replace ln_priceLoop = ln_priceLoop+Ddemand*gap;

	drop demand Ddemand gap;

	/* Exit if converged */

	if `j'==1000 | `gap'<10^-4 {;
		di `j' _skip(5) `gap';

		egen ln_mpCF = min(ln_priceLoop), by(bondid);
		gen gap = `gap';

		continue, break;
	};
};

#delimit ;
/* Construct variables */
sort date bondid fundid;
qui by date bondid: keep if _n==1;

/* Construct yield changes */
gen price_CF = exp(ln_mpCF)*100;
gen yield_CF = -ln_mpCF/timetomat;
gen CF_pc_yield = 100*(yield_CF - yield)/yield;
gen CF_chg_yield = 100*(yield_CF - yield);


save "${revisiondata}/counterfactuals/cf_seventeen_`q'.dta", replace;


};
};

#delimit cr



/* -----------------------------------------------------------------------------

Counterfactual 18: Run on largest ETFs - ETFs absorb 

------------------------------------------------------------------------------*/


clear all
set more off

set varabbrev off

******************************************************************************
* Specify working directory
******************************************************************************

* For example
* cd "/Users/.../XYZ/"

global rawdata "Data/Raw_Data"
global tempdata "Data/RevisionRFS/temp_data"
global masterdata "Data/Master_Data"
global revisiondata "Data/RevisionRFS"
global revisionfigures = "Results/RevisionRFS/Figures"
global revisionoutput = "Results/RevisionRFS/Output"

clear all
set more off
set type double

#delimit ;

forval q = `=tq(2006q1)'(1)`=tq(2020q3)' {;

di %tq `q';

use "${revisiondata}/counterfactuals/Large_etf.dta", clear;

keep if date==`q';

if etf_holdings_vs_tot > 0.04{;

#delimit ;
/* Load Data */
u "${revisiondata}/counterfactuals/counterfactuals_data.dta", clear;
keep if date==`q' & LNrweight_conditional<.;


/* Generate counterfactual variable */
qui merge m:1 date fundid using "${revisiondata}/counterfactuals/Large_etf.dta";
drop if _merge == 2;
drop _merge;
replace large_etf = 0 if large_etf ==.;

/* Dollars aum by investor group */
bysort date fundid: gen aum_fund = aum_tot if _n == 1;
replace aum_fund = 0 if aum_fund == .;
bysort type_new2 large_etf: gegen aum_type = sum(aum_fund);
gegen tot_aum_obs = sum(aum_fund) if type_new2 != 0;
gen frac_aum_type = aum_tot/aum_type if type_new2 != 0;

/* Counterfactual total aum for all large MFs */
gen aum_type_cf = aum_type*0.5 if type_new2 == 5 & large_etf == 1;

/* Assign difference in aum of large MFs to other MFs */
gen diff_aum_type_etf = aum_type - aum_type_cf if type_new2 == 5 & large_etf == 1;
gegen diff_aum_type_etf_all = mean(diff_aum_type_etf);
replace aum_type_cf = aum_type + diff_aum_type_etf_all if type_new2 == 5 & large_etf == 0;

/* Counterfactual total aum by investor */
gen aum_tot_cf = aum_type_cf*frac_aum_type if type_new2 == 5;

/* Counterfactual aum residual - stays the same (otherwise fraction observed would change!) */
replace aum_tot_cf = aum_tot if type_new2 <=4;
replace aum_tot_cf = aum_tot if type_new2 >=6;

/* Impose downward sloping demand as in KY (2019) */
replace _b_ss_price_iv = 0.99 if _b_ss_price_iv >= 1; 

/* Initial guess for price */
gen ln_priceLoop = ln_mp;

/* Set characteristics */
gen LNtimetomatLoop = LNtimetomat;  
gen spreadLoop = spread;
gen LNbvLoop = LNbv; 
gen coupon_decLoop = coupon_dec; 
gen rating_numLoop = rating_num;  

/* Set AUM */
gen aumLoop = aum_tot_cf;

/* Calculate within credit rating group latent demand (epsilon) plus the constant */
gen const_eps = LNrweight_conditional - (_b_ss_price_iv*ln_mp + _b_ss_price_tmt*LNtimetomat + _b_ss_price_spread*spread + _b_ss_price_bv*LNbv + _b_ss_price_rating*rating_num + _b_ss_price_coupon*coupon_dec);

/* Calculate across credit rating group latent demand (xi) plus fixed effect (alpha) */
gen alpha_xi = LNweight_assetclass - (LNoutweight_conditional1*_b_LNoutweight_conditional1 +LNoutweight_conditional2*_b_LNoutweight_conditional2);

/* Alpha_xi is only defined for one credit rating group --> set to zero otherwise */
replace alpha_xi = 0 if assetclass == 2;
replace alpha_xi = 0 if exclusive == 1;


/* Set coefficients */
foreach var of varlist _b_ss_price_iv _b_ss_price_tmt _b_ss_price_spread _b_ss_price_bv _b_ss_price_rating _b_ss_price_coupon{;
	gen `var'Loop = `var';
	};

/* Set the latent variable for within credit rating group */
gen latent = _b_ss_price_tmtLoop*LNtimetomatLoop + _b_ss_price_spreadLoop*spreadLoop + _b_ss_price_bvLoop*LNbvLoop + _b_ss_price_ratingLoop*rating_numLoop + 
 _b_ss_price_couponLoop*coupon_decLoop + const_eps;


#delimit ;

/* Solve for price */
forval j = 1/500 {;
	
	#delimit ;
	
	/* Update within credit rating group weights */

	gen double delta = exp(_b_ss_price_ivLoop*ln_priceLoop+latent);
	gegen double sum_delta = sum(delta), by(date fundid assetclass);

	gen double weight_conditional = delta/(1+sum_delta);
	
	#delimit ;
	/* Update across credit rating group weights */
	
	gen double inclusive_value = 1+sum_delta;
	
	gen double numerator = ( (inclusive_value)^lambda )*exp(alpha_xi);
	
	gen double numerator_once = numerator;
	bysort date fundid assetclass: replace numerator_once = 0 if _n != 1;
	
	gegen double denominator = sum(numerator_once), by(date fundid);

    gen double weight_across = numerator/denominator;
	
	
	#delimit ;
	/* Update bond specific weights */

	gen double weight = weight_conditional*weight_across;
	
	gegen double demand = sum(aumLoop*weight), by(date bondid);
	
	gegen double Ddemand = sum(aumLoop*( lambda*_b_ss_price_ivLoop*weight_conditional*weight_across*(1-weight_across)*weight_conditional + _b_ss_price_ivLoop*weight_conditional*(1-weight_conditional)*weight_across )/demand), by(date bondid);
	replace Ddemand = 1/(1-min(0,Ddemand));

	drop delta sum_delta weight_conditional inclusive_value numerator numerator_once denominator weight_across weight;

	/* Check convergence - Market Clearing */

	gen gap = ln(demand)-ln_priceLoop-LNbvLoop;

	sum gap;
	local gap = max(abs(r(min)),abs(r(max)));

	/* Update price */

	replace ln_priceLoop = ln_priceLoop+Ddemand*gap;

	drop demand Ddemand gap;

	/* Exit if converged */

	if `j'==1000 | `gap'<10^-4 {;
		di `j' _skip(5) `gap';

		egen ln_mpCF = min(ln_priceLoop), by(bondid);
		gen gap = `gap';

		continue, break;
	};
};

#delimit ;
/* Construct variables */
sort date bondid fundid;
qui by date bondid: keep if _n==1;

/* Construct yield changes */
gen price_CF = exp(ln_mpCF)*100;
gen yield_CF = -ln_mpCF/timetomat;
gen CF_pc_yield = 100*(yield_CF - yield)/yield;
gen CF_chg_yield = 100*(yield_CF - yield);


save "${revisiondata}/counterfactuals/cf_eightteen_`q'.dta", replace;


};
};

#delimit cr




/* -----------------------------------------------------------------------------

Counterfactual 19: Run on largest ETFs - Life insurers absorb 

------------------------------------------------------------------------------*/


clear all
set more off

set varabbrev off

******************************************************************************
* Specify working directory
******************************************************************************

* For example
* cd "/Users/.../XYZ/"

global rawdata "Data/Raw_Data"
global tempdata "Data/RevisionRFS/temp_data"
global masterdata "Data/Master_Data"
global revisiondata "Data/RevisionRFS"
global revisionfigures = "Results/RevisionRFS/Figures"
global revisionoutput = "Results/RevisionRFS/Output"

clear all
set more off
set type double

#delimit ;

forval q = `=tq(2006q1)'(1)`=tq(2020q3)' {;

di %tq `q';

use "${revisiondata}/counterfactuals/Large_etf.dta", clear;

keep if date==`q';

if etf_holdings_vs_tot > 0.04{;

#delimit ;
/* Load Data */
u "${revisiondata}/counterfactuals/counterfactuals_data.dta", clear;
keep if date==`q' & LNrweight_conditional<.;


/* Generate counterfactual variable */
qui merge m:1 date fundid using "${revisiondata}/counterfactuals/Large_etf.dta";
drop if _merge == 2;
drop _merge;
replace large_etf = 0 if large_etf ==.;

/* Dollars aum by investor group */
bysort date fundid: gen aum_fund = aum_tot if _n == 1;
replace aum_fund = 0 if aum_fund == .;
bysort type_new2 large_etf: gegen aum_type = sum(aum_fund);
gegen tot_aum_obs = sum(aum_fund) if type_new2 != 0;
gen frac_aum_type = aum_tot/aum_type if type_new2 != 0;

/* Counterfactual total aum for all large MFs */
gen aum_type_cf = aum_type*0.5 if type_new2 == 5 & large_etf == 1;

/* Assign difference in aum of large MFs to other MFs */
gen diff_aum_type_mf = aum_type - aum_type_cf if type_new2 == 5 & large_etf == 1;
gegen diff_aum_type_mf_all = mean(diff_aum_type_mf);
replace aum_type_cf = aum_type + diff_aum_type_mf_all if type_new2 == 1;

/* Counterfactual total aum by investor */
gen aum_tot_cf = aum_type_cf*frac_aum_type if type_new2 == 5 & large_etf == 1;
replace aum_tot_cf = aum_type_cf*frac_aum_type if type_new2 == 1;
replace aum_tot_cf = aum_tot if type_new2 == 5 & large_etf == 0;

/* Counterfactual aum residual - stays the same (otherwise fraction observed would change!) */
replace aum_tot_cf = aum_tot if type_new2 ==0;
replace aum_tot_cf = aum_tot if type_new2 ==2;
replace aum_tot_cf = aum_tot if type_new2 ==3;
replace aum_tot_cf = aum_tot if type_new2 ==4;
replace aum_tot_cf = aum_tot if type_new2 >=6;

/* Impose downward sloping demand as in KY (2019) */
replace _b_ss_price_iv = 0.99 if _b_ss_price_iv >= 1; 

/* Initial guess for price */
gen ln_priceLoop = ln_mp;

/* Set characteristics */
gen LNtimetomatLoop = LNtimetomat;  
gen spreadLoop = spread;
gen LNbvLoop = LNbv; 
gen coupon_decLoop = coupon_dec; 
gen rating_numLoop = rating_num;  

/* Set AUM */
gen aumLoop = aum_tot_cf;

/* Calculate within credit rating group latent demand (epsilon) plus the constant */
gen const_eps = LNrweight_conditional - (_b_ss_price_iv*ln_mp + _b_ss_price_tmt*LNtimetomat + _b_ss_price_spread*spread + _b_ss_price_bv*LNbv + _b_ss_price_rating*rating_num + _b_ss_price_coupon*coupon_dec);

/* Calculate across credit rating group latent demand (xi) plus fixed effect (alpha) */
gen alpha_xi = LNweight_assetclass - (LNoutweight_conditional1*_b_LNoutweight_conditional1 +LNoutweight_conditional2*_b_LNoutweight_conditional2);

/* Alpha_xi is only defined for one credit rating group --> set to zero otherwise */
replace alpha_xi = 0 if assetclass == 2;
replace alpha_xi = 0 if exclusive == 1;


/* Set coefficients */
foreach var of varlist _b_ss_price_iv _b_ss_price_tmt _b_ss_price_spread _b_ss_price_bv _b_ss_price_rating _b_ss_price_coupon{;
	gen `var'Loop = `var';
	};

/* Set the latent variable for within credit rating group */
gen latent = _b_ss_price_tmtLoop*LNtimetomatLoop + _b_ss_price_spreadLoop*spreadLoop + _b_ss_price_bvLoop*LNbvLoop + _b_ss_price_ratingLoop*rating_numLoop + 
 _b_ss_price_couponLoop*coupon_decLoop + const_eps;


#delimit ;

/* Solve for price */
forval j = 1/500 {;
	
	#delimit ;
	
	/* Update within credit rating group weights */

	gen double delta = exp(_b_ss_price_ivLoop*ln_priceLoop+latent);
	gegen double sum_delta = sum(delta), by(date fundid assetclass);

	gen double weight_conditional = delta/(1+sum_delta);
	
	#delimit ;
	/* Update across credit rating group weights */
	
	gen double inclusive_value = 1+sum_delta;
	
	gen double numerator = ( (inclusive_value)^lambda )*exp(alpha_xi);
	
	gen double numerator_once = numerator;
	bysort date fundid assetclass: replace numerator_once = 0 if _n != 1;
	
	gegen double denominator = sum(numerator_once), by(date fundid);

    gen double weight_across = numerator/denominator;
	
	
	#delimit ;
	/* Update bond specific weights */

	gen double weight = weight_conditional*weight_across;
	
	gegen double demand = sum(aumLoop*weight), by(date bondid);
	
	gegen double Ddemand = sum(aumLoop*( lambda*_b_ss_price_ivLoop*weight_conditional*weight_across*(1-weight_across)*weight_conditional + _b_ss_price_ivLoop*weight_conditional*(1-weight_conditional)*weight_across )/demand), by(date bondid);
	replace Ddemand = 1/(1-min(0,Ddemand));

	drop delta sum_delta weight_conditional inclusive_value numerator numerator_once denominator weight_across weight;

	/* Check convergence - Market Clearing */

	gen gap = ln(demand)-ln_priceLoop-LNbvLoop;

	sum gap;
	local gap = max(abs(r(min)),abs(r(max)));

	/* Update price */

	replace ln_priceLoop = ln_priceLoop+Ddemand*gap;

	drop demand Ddemand gap;

	/* Exit if converged */

	if `j'==1000 | `gap'<10^-4 {;
		di `j' _skip(5) `gap';

		egen ln_mpCF = min(ln_priceLoop), by(bondid);
		gen gap = `gap';

		continue, break;
	};
};

#delimit ;
/* Construct variables */
sort date bondid fundid;
qui by date bondid: keep if _n==1;

/* Construct yield changes */
gen price_CF = exp(ln_mpCF)*100;
gen yield_CF = -ln_mpCF/timetomat;
gen CF_pc_yield = 100*(yield_CF - yield)/yield;
gen CF_chg_yield = 100*(yield_CF - yield);


save "${revisiondata}/counterfactuals/cf_nineteen_`q'.dta", replace;


};
};

#delimit cr





